package cn.zifangsky.controller;

import cn.zifangsky.license.*;
import cn.zifangsky.repository.entity.License;
import cn.zifangsky.service.itf.LicenseService;
import com.keyware.kd.context.Token;
import com.keyware.kd.controller.BaseController;
import com.keyware.kd.exception.SecuritySetException;
import com.keyware.kd.task.util.AjaxMessage;
import com.keyware.kd.utils.Constant;
import com.keyware.utils.AESUtils;
import com.keyware.utils.DateUtils;
import com.keyware.utils.IdGenerator;
import de.schlichtherle.license.LicenseContent;
import de.schlichtherle.license.LicenseContentException;
import de.schlichtherle.license.LicenseManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.*;

/**
 * <p>
 * 授权文件表 前端控制器
 * </p>
 *
 * @author swq
 * @since 2022-02-25
 */
@Controller
@RequestMapping("/license")
public class LicenseController extends BaseController {

    private final String webRootPath = LicenseCheckListener.getWebRootAbsolutePath().substring(1, LicenseCheckListener.getWebRootAbsolutePath().length() - 1);
    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    @Value("${license.subject}")
    private String subject;

    @Value("${license.publicAlias}")
    private String publicAlias;

    @Value("${license.storePass}")
    private String storePass;

    @Autowired
    private LicenseService  licenseService;


    /**
     *
     * @Title: uploadLicFile
     * @Description: 上传授权文件
     * @param
     * @param multipartfile
     * @return
     * @author 贺雷雷
     * @return String
     * @throws IOException
     */
    @Token(validate = true)
    @RequestMapping(value = "/uploadLicFile", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ResponseBody
    public AjaxMessage uploadLicFile(@RequestParam MultipartFile multipartfile) throws IOException {
        AjaxMessage ajaxMessage = new AjaxMessage();
        ajaxMessage.setCode("0");
        StringBuffer sb = new StringBuffer("3532263592381276");
        InputStream inputStream = multipartfile.getInputStream();
        byte[] filedata = new byte[(int) multipartfile.getSize()];
        inputStream.read(filedata);
        LicenseVerifyParam param = new LicenseVerifyParam();
        param.setSubject(subject);//证书subject
        param.setPublicAlias(publicAlias);// 公钥别称
        param.setStorePass(storePass);//访问公钥库的密码
        String scriptPath = File.separator+webRootPath + File.separator;
        param.setPublicKeysStorePath(scriptPath+"publicCerts.keystore");  //密钥库存储路径
        LicenseVerify licenseVerify = new LicenseVerify();
        String fileName = multipartfile.getOriginalFilename();
        String byteArrayToHexString = byteArrayToHexString(filedata);
        //实现文件的上传
        multipartfile.transferTo(new File(scriptPath+fileName));
        LicenseContent result = null;
        //1. 安装证书
        try{
            LicenseManager licenseManager = LicenseManagerHolder.getInstance(licenseVerify.initLicenseParam(param));
            licenseManager.uninstall();
            result = licenseManager.install(new File(scriptPath+fileName));
            LicenseCheckModel expectedCheckModel = (LicenseCheckModel) result.getExtra();
            String code = expectedCheckModel.getCode();
            String day = expectedCheckModel.getDay();
            String startTime=expectedCheckModel.getStartTime();
            String endTime=expectedCheckModel.getEndTime();
            if(null==startTime||null==endTime) {
                ajaxMessage.setMessage("证书生效时间范围不能为空");
                return ajaxMessage;
            }
            if(DateUtils.before(DateUtils.getDate(),startTime)||DateUtils.before(endTime,DateUtils.getDate())) {
                ajaxMessage.setMessage("证书已失效请联系厂家");
                return ajaxMessage;
            }
            License lic=new License();
            List<License> list = licenseService.list();
            if(list.size()==0&&null!=day&&!day.equals("0")) {
                Date date = new Date();
                lic.setId(IdGenerator.uuid32());
                lic.setCreateDate(AESUtils.encrypt(DateUtils.getMillis(date)+"",sb.toString()));
                lic.setSyDate(AESUtils.encrypt(DateUtils.getMillis(date)+"",sb.toString()));
                lic.setLicenseStatus(new Random().nextInt(9999)+AESUtils.encrypt("1",sb.toString())+new Random().nextInt(9999));
                lic.setLicenseContext(filedata);
                lic.setDataContext(AESUtils.encrypt(AESUtils.identityToString(lic),sb.toString()));
                licenseService.saveLic(lic);

                ajaxMessage.setCode("1");
                ajaxMessage.setMessage(MessageFormat.format("证书安装成功，证书授权天数：{0} ",expectedCheckModel.getDay()));
            }
            if(list.size()>0&&null!=day&&!day.equals("0")){
                Map<String,License> map = new HashMap<String,License>(list.size());
                for(License  con : list){
                    map.put(byteArrayToHexString(con.getLicenseContext()),con);
                }
                if(!map.containsKey(byteArrayToHexString)) {
                    License one = licenseService.getOne(AESUtils.encrypt("1",sb.toString()));
                    if(null!=one) {
                        one.setLicenseStatus(new Random().nextInt(9999)+AESUtils.encrypt("0",sb.toString())+new Random().nextInt(9999));
                        one.setDataContext(AESUtils.encrypt(AESUtils.identityToString(one),sb.toString()));
                        licenseService.updateByIdLic(one);
                    }
                    Date date = new Date();
                    lic.setId(IdGenerator.uuid32());
                    lic.setCreateDate(AESUtils.encrypt(DateUtils.getMillis(date)+"",sb.toString()));
                    lic.setSyDate(AESUtils.encrypt(DateUtils.getMillis(date)+"",sb.toString()));
                    lic.setLicenseStatus(new Random().nextInt(9999)+AESUtils.encrypt("1",sb.toString())+new Random().nextInt(9999));
                    lic.setLicenseContext(filedata);
                    lic.setDataContext(AESUtils.encrypt(AESUtils.identityToString(lic),sb.toString()));
                    licenseService.saveLic(lic);

                    ajaxMessage.setCode("1");
                    ajaxMessage.setMessage(MessageFormat.format("证书安装成功，证书授权天数：{0} ",expectedCheckModel.getDay()));
                }else {
                    ajaxMessage.setMessage("证书已存在，请检查");
                    logger.error("证书已存在");
                }
            }
        }catch (LicenseContentException e){
            ajaxMessage.setMessage("证书安装失败");
        }catch (Exception e){
            ajaxMessage.setMessage("证书安装失败");
        }
        return ajaxMessage;
    }
    @Token(create = true)
    @RequestMapping(value = "/webservice/showAddLicFile",method = RequestMethod.GET,produces = "application/json; charset=utf-8")
    public ModelAndView showAddProjectFile(){
        ModelAndView modelAndView = new ModelAndView(Constant.projectName+"/lic/showAddLicFile");
        return modelAndView;
    }
    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));
        return resultSb.toString();
    }
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
}